home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / trace / tcpdump-2.2.1 / print-atalk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-26  |  11.0 KB  |  479 lines

  1. /*
  2.  * Copyright (c) 1988-1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * Format and print AppleTalk packets.
  22.  */
  23. #ifndef lint
  24. static  char rcsid[] =
  25.     "@(#)$Header: print-atalk.c,v 1.22 92/03/26 14:15:34 mccanne Exp $ (LBL)";
  26. #endif
  27.  
  28. #ifdef __STDC__
  29. #include <stdlib.h>
  30. #endif
  31. #include <stdio.h>
  32.  
  33. #include <sys/param.h>
  34. #include <sys/types.h>
  35. #include <sys/socket.h>
  36. #include <netinet/in.h>
  37. #include <netinet/in_systm.h>
  38. #include <netinet/ip.h>
  39. #include <netinet/ip_var.h>
  40. #include <netinet/udp.h>
  41. #include <netinet/udp_var.h>
  42. #include <netinet/tcp.h>
  43. #include <netinet/tcpip.h>
  44.  
  45. #include "interface.h"
  46. #include "addrtoname.h"
  47. #include "appletalk.h"
  48. #include <strings.h>
  49. #include "extract.h"
  50.  
  51. static char *ataddr_string();
  52. static struct atNBPtuple *nbp_tuple_print();
  53. static struct atNBPtuple *nbp_name_print();
  54. static void atp_print();
  55. static void nbp_print();
  56. static void atp_bitmap_print();
  57.  
  58. /*
  59.  * Print AppleTalk Datagram Delivery Protocol packets.
  60.  */
  61. void
  62. ddp_print(dp, length)
  63.     register struct atDDP *dp;
  64.     int length;
  65. {
  66.     if (length < ddpSize) {
  67.         (void)printf(" truncated-ddp %d", length);
  68.         return;
  69.     }
  70.     (void)printf("%s.%d > %s.%d:",
  71.              ataddr_string(EXTRACT_SHORT(&dp->srcNet), dp->srcNode),
  72.              dp->srcSkt,
  73.              ataddr_string(EXTRACT_SHORT(&dp->dstNet), dp->dstNode),
  74.              dp->dstSkt);
  75.  
  76.     /* 'type' is the last field of 'dp' so we need the whole thing.
  77.        If we cannot determine the type, bail out.  (This last byte
  78.        happens to be *one* byte past the end of tcpdump's minimum
  79.        snapshot length.) */
  80.     if ((u_char *)(dp + 1) > snapend) {
  81.         printf(" [|atalk]");
  82.         return;
  83.     }
  84.  
  85.     length -= ddpSize;
  86.     switch (dp->type) {
  87.  
  88.     case ddpRTMP:
  89.         (void)printf(" at-rtmp %d", length);
  90.         break;
  91.     case ddpRTMPrequest:
  92.         (void)printf(" at-rtmpReq %d", length);
  93.         break;
  94.     case ddpNBP:
  95.         nbp_print((struct atNBP *)((u_char *)dp + ddpSize),
  96.               length, dp);
  97.         break;
  98.     case ddpATP:
  99.         atp_print((struct atATP *)((u_char *)dp + ddpSize), length);
  100.         break;
  101.     case ddpECHO:
  102.         (void)printf(" at-echo %d", length);
  103.         break;
  104.     case ddpIP:
  105.         (void)printf(" at-IP %d", length);
  106.         break;
  107.     case ddpARP:
  108.         (void)printf(" at-ARP %d", length);
  109.         break;
  110.     case ddpKLAP:
  111.         (void)printf(" at-KLAP %d", length);
  112.         break;
  113.     default:
  114.         (void)printf(" at-#%d %d", length);
  115.         break;
  116.     }
  117. }
  118.  
  119. static void
  120. atp_print(ap, length)
  121.     register struct atATP *ap;
  122.     int length;
  123. {
  124.     char c;
  125.     long data;
  126.  
  127.     if ((u_char *)(ap + 1) > snapend) {
  128.         /* Just bail if we don't have the whole chunk. */
  129.         printf(" [|atalk]");
  130.         return;
  131.     }
  132.     length -= sizeof(*ap);
  133.     switch (ap->control & 0xc0) {
  134.  
  135.     case atpReqCode:
  136.         (void)printf(" atp-req%s %d",
  137.                  ap->control & atpXO? " " : "*",
  138.                  EXTRACT_SHORT(&ap->transID));
  139.  
  140.         atp_bitmap_print(ap->bitmap);
  141.  
  142.         if (length != 0)
  143.             (void)printf(" [len=%d]", length);
  144.  
  145.         switch (ap->control & (atpEOM|atpSTS)) {
  146.         case atpEOM:
  147.             (void)printf(" [EOM]");
  148.             break;
  149.         case atpSTS:
  150.             (void)printf(" [STS]");
  151.             break;
  152.         case atpEOM|atpSTS:
  153.             (void)printf(" [EOM,STS]");
  154.             break;
  155.         }
  156.         break;
  157.  
  158.     case atpRspCode:
  159.         (void)printf(" atp-resp%s%d:%d (%d)",
  160.                  ap->control & atpEOM? "*" : " ",
  161.                  EXTRACT_SHORT(&ap->transID), ap->bitmap, length);
  162.         switch (ap->control & (atpXO|atpSTS)) {
  163.         case atpXO:
  164.             (void)printf(" [XO]");
  165.             break;
  166.         case atpSTS:
  167.             (void)printf(" [STS]");
  168.             break;
  169.         case atpXO|atpSTS:
  170.             (void)printf(" [XO,STS]");
  171.             break;
  172.         }
  173.         break;
  174.  
  175.     case atpRelCode:
  176.         (void)printf(" atp-rel  %d", EXTRACT_SHORT(&ap->transID));
  177.  
  178.         atp_bitmap_print(ap->bitmap);
  179.  
  180.         /* length should be zero */
  181.         if (length)
  182.             (void)printf(" [len=%d]", length);
  183.  
  184.         /* there shouldn't be any control flags */
  185.         if (ap->control & (atpXO|atpEOM|atpSTS)) {
  186.             c = '[';
  187.             if (ap->control & atpXO) {
  188.                 (void)printf("%cXO", c);
  189.                 c = ',';
  190.             }
  191.             if (ap->control & atpEOM) {
  192.                 (void)printf("%cEOM", c);
  193.                 c = ',';
  194.             }
  195.             if (ap->control & atpSTS) {
  196.                 (void)printf("%cSTS", c);
  197.                 c = ',';
  198.             }
  199.             (void)printf("]");
  200.         }
  201.         break;
  202.  
  203.     default:
  204.         (void)printf(" atp-0x%x  %d (%d)", ap->control, 
  205.                  EXTRACT_SHORT(&ap->transID), length);
  206.         break;
  207.     }
  208.     data = EXTRACT_LONG(&ap->userData);
  209.     if (data != 0)
  210.         (void)printf(" 0x%x", data);
  211. }
  212.  
  213. static void
  214. atp_bitmap_print(bm)
  215.     register u_char bm;
  216. {
  217.     register char c;
  218.     register int i;
  219.  
  220.     /* 
  221.      * The '& 0xff' below is needed for compilers that want to sign
  222.      * extend a u_char, which is the case with the Ultrix compiler.
  223.      * (gcc is smart enough to eliminate it, at least on the Sparc).
  224.      */
  225.     if ((bm + 1) & (bm & 0xff)) {
  226.         c = '<';
  227.         for (i = 0; bm; ++i) {
  228.             if (bm & 1) {
  229.                 (void)printf("%c%d", c, i);
  230.                 c = ',';
  231.             }
  232.             bm >>= 1;
  233.         }
  234.         (void)printf(">");
  235.     } else {
  236.         for (i = 0; bm; ++i)
  237.             bm >>= 1;
  238.         if (i > 1)
  239.             (void)printf("<0-%d>", i - 1);
  240.         else
  241.             (void)printf("<0>");
  242.     }
  243. }
  244.  
  245. static void
  246. nbp_print(np, length, dp)
  247.     register struct atNBP *np;
  248.     int length;
  249.     register struct atDDP *dp;
  250. {
  251.     register struct atNBPtuple *tp =
  252.             (struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
  253.     int i = length;
  254.     u_char *ep;
  255.  
  256.     length -= nbpHeaderSize;
  257.     if (length < 8) {
  258.         /* must be room for at least one tuple */
  259.         (void)printf(" truncated-nbp %d", length + nbpHeaderSize);
  260.         return;
  261.     }
  262.     /* ep points to end of available data */
  263.     ep = snapend;
  264.     if ((u_char *)tp > ep) {
  265.         printf(" [|atalk]");
  266.         return;
  267.     }
  268.     switch (i = np->control & 0xf0) {
  269.  
  270.     case nbpBrRq:
  271.     case nbpLkUp:
  272.         (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:",
  273.                  np->id);
  274.         if ((u_char *)(tp + 1) > ep) {
  275.             printf(" [|atalk]");
  276.             return;
  277.         }
  278.         (void)nbp_name_print(tp, ep);
  279.         /*
  280.          * look for anomalies: the spec says there can only
  281.          * be one tuple, the address must match the source
  282.          * address and the enumerator should be zero.
  283.          */
  284.         if ((np->control & 0xf) != 1)
  285.             (void)printf(" [ntup=%d]", np->control & 0xf);
  286.         if (tp->enumerator)
  287.             (void)printf(" [enum=%d]", tp->enumerator);
  288.         if (EXTRACT_SHORT(&tp->net) != EXTRACT_SHORT(&dp->srcNet) ||
  289.             tp->node != dp->srcNode || tp->skt != dp->srcSkt)
  290.             (void)printf(" [addr=%s.%d]",
  291.                      ataddr_string(EXTRACT_SHORT(&tp->net), 
  292.                            tp->node), 
  293.                      tp->skt);
  294.         break;
  295.  
  296.     case nbpLkUpReply:
  297.         (void)printf(" nbp-reply %d:", np->id);
  298.  
  299.         /* print each of the tuples in the reply */
  300.         for (i = np->control & 0xf; --i >= 0 && tp; )
  301.             tp = nbp_tuple_print(tp, ep, dp);
  302.         break;
  303.  
  304.     default:
  305.         (void)printf(" nbp-0x%x  %d (%d)", np->control, np->id,
  306.                 length);
  307.         break;
  308.     }
  309. }
  310.  
  311. /* print a counted string */
  312. static char *
  313. print_cstring(cp, ep)
  314.     register char *cp;
  315.     register u_char *ep;
  316. {
  317.     register int length;
  318.  
  319.     if (cp >= (char *)ep) {
  320.         (void)printf("[|atalk]");
  321.         return (0);
  322.     }
  323.     length = *cp++;
  324.  
  325.     /* Spec says string can be at most 32 bytes long */
  326.     if (length < 0 || length > 32) {
  327.         (void)printf("[len=%d]", length);
  328.         return (0);
  329.     }
  330.     while (--length >= 0) {
  331.         if (cp >= (char *)ep) {
  332.             (void)printf("[|atalk]");
  333.             return (0);
  334.         }
  335.         putchar(*cp++);
  336.     }
  337.     return (cp);
  338. }
  339.  
  340. static struct atNBPtuple *
  341. nbp_tuple_print(tp, ep, dp)
  342.     register struct atNBPtuple *tp;
  343.     register u_char *ep;
  344.     register struct atDDP *dp;
  345. {
  346.     register struct atNBPtuple *tpn;
  347.  
  348.     if ((u_char *)(tp + 1) > ep) {
  349.         printf(" [|atalk]");
  350.         return 0;
  351.     }
  352.     tpn = nbp_name_print(tp, ep);
  353.  
  354.     /* if the enumerator isn't 1, print it */
  355.     if (tp->enumerator != 1)
  356.         (void)printf("(%d)", tp->enumerator);
  357.  
  358.     /* if the socket doesn't match the src socket, print it */
  359.     if (tp->skt != dp->srcSkt)
  360.         (void)printf(" %d", tp->skt);
  361.  
  362.     /* if the address doesn't match the src address, it's an anomaly */
  363.     if (EXTRACT_SHORT(&tp->net) != EXTRACT_SHORT(&dp->srcNet) ||
  364.         tp->node != dp->srcNode)
  365.         (void)printf(" [addr=%s]",
  366.                  ataddr_string(EXTRACT_SHORT(&tp->net), tp->node));
  367.  
  368.     return (tpn);
  369. }
  370.  
  371. static struct atNBPtuple *
  372. nbp_name_print(tp, ep)
  373.     struct atNBPtuple *tp;
  374.     register u_char *ep;
  375. {
  376.     register char *cp = (char *)tp + nbpTupleSize;
  377.  
  378.     putchar(' ');
  379.  
  380.     /* Object */
  381.     putchar('"');
  382.     if (cp = print_cstring(cp, ep)) {
  383.         /* Type */
  384.         putchar(':');
  385.         if (cp = print_cstring(cp, ep)) {
  386.             /* Zone */
  387.             putchar('@');
  388.             if (cp = print_cstring(cp, ep))
  389.                 putchar('"');
  390.         }
  391.     }
  392.     return ((struct atNBPtuple *)cp);
  393. }
  394.  
  395.  
  396. #define HASHNAMESIZE 4096
  397.  
  398. struct hnamemem {
  399.     int addr;
  400.     char *name;
  401.     struct hnamemem *nxt;
  402. };
  403.  
  404. static struct hnamemem hnametable[HASHNAMESIZE];
  405.  
  406. static char *
  407. ataddr_string(atnet, athost)
  408.     u_short atnet;
  409.     u_char athost;
  410. {
  411.     register struct hnamemem *tp, *tp2;
  412.     register int i = (atnet << 8) | athost;
  413.     char nambuf[256];
  414.     static int first = 1;
  415.     FILE *fp;
  416.  
  417.     /*
  418.      * if this is the first call, see if there's an AppleTalk
  419.      * number to name map file.
  420.      */
  421.     if (first && (first = 0, !nflag)
  422.         && (fp = fopen("/etc/atalk.names", "r"))) {
  423.         char line[256];
  424.         int i1, i2, i3;
  425.  
  426.         while (fgets(line, sizeof(line), fp)) {
  427.             if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
  428.                 continue;
  429.             if (sscanf(line, "%d.%d.%d %s", &i1, &i2, &i3,
  430.                      nambuf) == 4)
  431.                 /* got a hostname. */
  432.                 i3 |= ((i1 << 8) | i2) << 8;
  433.             else if (sscanf(line, "%d.%d %s", &i1, &i2,
  434.                     nambuf) == 3)
  435.                 /* got a net name */
  436.                 i3 = (((i1 << 8) | i2) << 8) | 255;
  437.             else
  438.                 continue;
  439.  
  440.             for (tp = &hnametable[i3 & (HASHNAMESIZE-1)];
  441.                  tp->nxt; tp = tp->nxt)
  442.                 ;
  443.             tp->addr = i3;
  444.             tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
  445.             i3 = strlen(nambuf) + 1;
  446.             tp->name = strcpy(malloc((unsigned) i3), nambuf);
  447.         }
  448.         fclose(fp);
  449.     }
  450.  
  451.     for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  452.         if (tp->addr == i)
  453.             return (tp->name);
  454.  
  455.     /* didn't have the node name -- see if we've got the net name */
  456.     i |= 255;
  457.     for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
  458.         if (tp2->addr == i) {
  459.             tp->addr = (atnet << 8) | athost;
  460.             tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
  461.             (void)sprintf(nambuf, "%s.%d", tp2->name, athost);
  462.             i = strlen(nambuf) + 1;
  463.             tp->name = strcpy(malloc((unsigned) i), nambuf);
  464.             return (tp->name);
  465.         }
  466.  
  467.     tp->addr = (atnet << 8) | athost;
  468.     tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
  469.     if (athost != 255)
  470.         (void)sprintf(nambuf, "%d.%d.%d",
  471.             atnet >> 8, atnet & 0xff, athost);
  472.     else
  473.         (void)sprintf(nambuf, "%d.%d", atnet >> 8, atnet & 0xff);
  474.     i = strlen(nambuf) + 1;
  475.     tp->name = strcpy(malloc((unsigned) i), nambuf);
  476.  
  477.     return (tp->name);
  478. }
  479.